/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.metadataRepository.repository.records.impl;

import cz.mzk.oai.metadataRepository.metadata.DateStamp;
import cz.mzk.oai.metadataRepository.metadata.MetadataFormat;
import cz.mzk.oai.metadataRepository.repository.Identifier;
import cz.mzk.oai.metadataRepository.repository.collections.MetadataCollection;
import cz.mzk.oai.metadataRepository.repository.records.NoSuchRecordException;
import cz.mzk.oai.metadataRepository.repository.records.Record;
import cz.mzk.oai.metadataRepository.repository.records.Manager;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;

/**
 *
 * @author Martin Řehánek (rehan at mzk.cz)
 */
public class ManagerFileImpl implements Manager {

    private static final Logger logger = Logger.getLogger(ManagerFileImpl.class.getName());
    private final FilePresentRecordsManager presentRecordsManager;
    private final FileDeletedRecordsManager deletedRecordsManager;

    public ManagerFileImpl(MetadataCollection collection) {
        presentRecordsManager = new FilePresentRecordsManager(collection);
        deletedRecordsManager = new FileDeletedRecordsManager(collection);
    }

    public Record createRecord(Identifier identifier, MetadataFormat format, Document metadata) throws IOException {
        presentRecordsManager.createRecord(identifier, format);
        presentRecordsManager.updateRecord(identifier, format, metadata);
        return presentRecordsManager.getRecord(identifier, format);
    }

    public Record createDeletedRecord(Identifier identifier, MetadataFormat format) throws IOException {
        deletedRecordsManager.createRecord(identifier, format);
        return deletedRecordsManager.getRecord(identifier, format);
    }

    public boolean contains(Identifier id, MetadataFormat metadataFormat) {
        return presentRecordsManager.contains(id, metadataFormat)
                || deletedRecordsManager.contains(id, metadataFormat);
    }

    public Record getRecord(Identifier identifier, MetadataFormat format) {
        if (presentRecordsManager.contains(identifier, format)) {
            return presentRecordsManager.getRecord(identifier, format);
        }
        if (deletedRecordsManager.contains(identifier, format)) {
            return deletedRecordsManager.getRecord(identifier, format);
        }
        return null;
    }

    public List<Record> getRecords(MetadataFormat format, DateStamp from, DateStamp until) {
        List<Record> presentRecords = presentRecordsManager.getRecords(format, from, until);
        List<Record> deletedRecords = deletedRecordsManager.getRecords(format, from, until);
        presentRecords.addAll(deletedRecords);
        return presentRecords;
    }

    public void updateRecord(Identifier identifier, MetadataFormat format, Document metadata) throws IOException {
        if (deletedRecordsManager.contains(identifier, format)) {
            deletedRecordsManager.deleteRecord(identifier, format);
            presentRecordsManager.createRecord(identifier, format);
        }
        presentRecordsManager.updateRecord(identifier, format, metadata);
    }

    public void setRecordDeleted(Identifier identifier, MetadataFormat format) throws IOException {
        if (presentRecordsManager.contains(identifier, format)) {
            presentRecordsManager.deleteRecord(identifier, format);
            deletedRecordsManager.createRecord(identifier, format);
        } else {
            logger.log(Level.WARNING, "record id: {0}, format: {1} is already deleted", new Object[]{identifier.toFilename(), format.toString()});
        }
    }

    public void deleteRecord(Identifier id, MetadataFormat metadataFormat) throws IOException, NoSuchRecordException {
        if (presentRecordsManager.contains(id, metadataFormat)) {
            presentRecordsManager.deleteRecord(id, metadataFormat);
        } else if (deletedRecordsManager.contains(id, metadataFormat)) {
            deletedRecordsManager.deleteRecord(id, metadataFormat);
        } else {
            throw new NoSuchRecordException(id, metadataFormat);
        }
    }
}
